<?php


namespace app\shop\controller\api;


use app\BaseController;
use app\enterprise\model\Friend;
use app\enterprise\model\GroupUser;
use app\enterprise\model\Message;
use app\enterprise\model\User;
use app\shop\model\chat\GroupUserModel;
use app\shop\model\file\FileModel;
use app\shop\model\order\OrderModel;
use app\shop\model\user\ChatUserModel;
use app\shop\model\user\MessageModel;
use app\shop\model\user\UserModel;
use app\shop\service\chat\ChatService;
use app\shop\service\chat\ChatVoiceService;
use app\shop\service\chat\MessageService;
use app\shop\service\config\ConfigService;
use app\shop\service\until\FileService;
use app\shop\service\until\TencentVideoService;
use app\shop\service\user\FriendService;
use app\shop\service\user\UserService;
use Exception;
use GatewayClient\Gateway;
use think\App;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;

class ImController extends BaseController
{
    protected $userInfo;
    protected $fileType = ['file', 'image', 'video', 'voice', 'emoticon'];

    public function __construct(App $app)
    {
        parent::__construct($app);
        $this->userInfo = $this->request->middleware('userInfo');
    }

    /**
     * 获取某个部门人
     * @return \think\response\Json
     */
    public function getDepartmentList()
    {
        try {
            $userInfo = $this->request->middleware('userInfo');
            $list = FriendService::getDepartmentFriendList($userInfo);
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 聊天列表
     * @return \think\response\Json
     */
    public function getContacts()
    {
        try {
            $userInfo = $this->request->middleware('userInfo');
            $search = $this->request->param('search', '', 'trim');
            $list = ChatService::getContactList($userInfo, $search);
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }


    /**
     * 发送消息
     * @return \think\response\Json
     */
    public function sendMessage()
    {
        Db::startTrans();
        try {
            $param = $this->request->param();
            $param['user_id'] = $this->request->middleware('userId');
            $data = Message::sendMessage($param);
            Db::commit();
            return $this->success($data);
        } catch (\Exception $exception) {
            Db::rollback();
            return $this->error($exception->getLine() . $exception->getMessage());
        }
    }


    /**
     * 聊天记录-聊天框内
     * @return \think\response\Json
     */
    public function getMessageList()
    {
        try {
            $chatSign = $this->request->param('chat_sign', '', 'trim');
            $type = $this->request->param('type', 'all', 'trim');
            $keywords = $this->request->param('keywords', '', 'trim');
            $page = $this->request->param('page', 1, 'int');
            $limit = $this->request->param('limit', 20, 'int');
            $userInfo = $this->request->middleware('userInfo');

            $messageService = new MessageService();
            $list = $messageService->getMessageList($userInfo, $chatSign, $type, $keywords, $page, $limit);
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 聊天记录-历史消息
     * @return \think\response\Json
     */
    public function getMessageRecord()
    {
        try {
            $upPage = $this->request->param('up_page', 1, 'int');
            $downPage = $this->request->param('down_page', 1, 'int');
            $listRows = $this->request->param('limit', 10, 'int');
            $isFirst = $this->request->param('is_first', 1, 'int');
            $msgId = $this->request->param('msg_id', 0, 'int');
            $chatSign = $this->request->param('chat_sign', '', 'trim');
            $search = $this->request->param('search', '', 'trim');
            // 0下拉加载以前的消息 1上拉加载以后的消息
            $directional = $this->request->param('directional', 1, 'int');

            $isRead = $this->request->param('is_read', 0, 'int');
            $type = $this->request->param('type', 'all', 'trim');
            $userInfo = $this->request->middleware('userInfo');

            $messageService = new MessageService();
            $list = $messageService->getMessageRecord($msgId, $userInfo, $chatSign, $listRows, $isFirst, $directional, $upPage, $downPage, $search, $isRead, $type);
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     * 设置当前窗口的消息默认为已读
     * @return \think\response\Json
     */
    public function setMsgIsRead()
    {
        try {
            $userId = $this->request->middleware('userId');
            $chatSign = $this->request->param('chat_sign', '', 'trim');
            MessageService::setIsRead($chatSign, $userId);
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }


    /**
     * 语音电话
     * @return \think\response\Json
     */
    public function sendToMsg()
    {
        try {
            $chatSign = $this->request->param('chat_sign', '', 'trim');
            $status = $this->request->param('status', '', 'trim');
            $event = $this->request->param('event', 'calling', 'trim');
            $sdp = $this->request->param('sdp', '', 'trim');
            $iceCandidate = $this->request->param('iceCandidate', '', 'trim');

            $id = $this->request->param('id', '', 'trim');
            $code = $this->request->param('code', 901, 'int');

            $fromUserId = $this->request->middleware('userId');
            MessageService::sendVoiceMsg($event, $code, $id, $fromUserId, $chatSign, $status, $sdp, $iceCandidate);
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage() . $exception->getLine());
        }
    }

    /**
     * 腾讯语音签名
     * @return \think\response\Json
     */
    public function getUserSign()
    {
        try {
            $appId = env('tencent.appid');
            $key = env('tencent.key');
            $userId = $this->request->middleware('userId');
            $tencentVideoService = new TencentVideoService($appId, $key);
            $sign = $tencentVideoService->genUserSig($userId);
            return $this->success($sign);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    // 撤回消息
    public function undoMessage()
    {
        try {
            $id = $this->request->param('id');
            $userInfo = $this->request->middleware('userInfo');
            $message = Message::where(['id' => $id])->find();
            if (!$message) {
                throw new \Exception('消息不存在');
            }
            // 如果时间超过了2分钟也不能撤回
            $createTime = is_string($message['create_time']) ? strtotime($message['create_time']) : $message['create_time'];
            if (time() - $createTime > 120 && $message['is_group'] == 0) {
                throw new \Exception('超过2分钟不能撤回！');
            }
            $text = "撤回了一条消息";
            $fromUserName = "对方";
            $toContactId = $message['to_user'];
            $message->content = str_encipher($text);
            $message->type = 'event';
            $message->is_undo = 1;
            $message->save();
            $info = $message->toArray();
            // $data = $info;
            $data['content'] = $fromUserName . $text;
            $data['sendTime'] = $createTime * 1000;
            $data['id'] = $info['id'];
            $data['from_user'] = $info['from_user'];
            $data['msg_id'] = $info['msg_id'];
            $data['status'] = $info['status'];
            $data['type'] = 'event';
            $data['isMobile'] = $this->request->isMobile() ? 1 : 0;

            $chatVoiceService = new ChatVoiceService();
            $chatVoiceService->setLastMessageToRedis($message['chat_sign'], $id, $text, 'event',
                $userInfo['user_id'], $userInfo['realname'], 1);

            wsSendMsg($message['chat_sign'], 'undoMessage', $data, 1);
            return $this->success();
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }

    /**
     *聊天列表
     * @return \think\response\Json
     */
    public function getContactList()
    {
        try {
            $where = [];
            $userId = $this->request->middleware('userId');
            $where[] = ['chat_status', '=', 1];
            $where[] = ['type', 'not in', ['event', 'system', 'new_order']];
            $where[] = ['from_user|to_user', '=', $userId];
            $where[] = ['del_user', '<>', $userId];
            $search = $this->request->param('search', '', 'trim');
            if ($search) {
                $uid = UserModel::where('realname|mobile', 'like', "%{$search}%")->value('user_id');
                $chatIdentify = chat_identify($uid, $userId);
                $where[] = ['chat_identify', '=', $chatIdentify];
            }
            $field = 'max(msg_id) as msg_id,is_group,at as is_at,chat_identify,from_user,to_user,order_id,chat_sign';
            $list = MessageModel::where($where)
                ->field($field)
                ->order('msg_id', 'desc')
                ->group('chat_sign')
                ->select();
            try {
                Gateway::$registerAddress = config('gateway.registerAddress');
                $onlineList = Gateway::getAllUidList();
            } catch (\Exception $e) {
                $onlineList = [];
            }
            foreach ($list as &$value) {
                $lastInfo = MessageModel::where('msg_id', $value['msg_id'])->find();
                $value['lastContent'] = $lastInfo['content'];
                $value['type'] = $lastInfo['type'];

                $unread = MessageModel::where('to_user', $userId)
                    ->where('from_user', '<>', 1)
                    ->where('type', '<>', 'event')
                    ->where('is_read', 0)
                    ->where('is_group', 0)
                    ->where('chat_status', 1)
                    ->where('del_user', '<>', $userId)
                    ->where('chat_sign', $value['chat_sign'])
                    ->count('msg_id');
                $value['unread'] = $unread;
                $lastSendTime = MessageModel::where('chat_sign', $value['chat_sign'])
                    ->where('type', '<>', 'event')
                    ->max('create_time');
                $value['lastSendTime'] = intval($lastSendTime * 1000);

                $friendId = $value['from_user'] == $userId ? $value['to_user'] : $value['from_user'];
                $friendInfo = UserModel::find($friendId);
                $value['user_id'] = $friendInfo['user_id'];
                $value['realname'] = $friendInfo['realname'];
                $value['account'] = $friendInfo['mobile'];
                $value['avatar'] = $friendInfo['avatar'];
                $value['login_status'] = $friendInfo['login_status'];
                $value['is_online'] = isset($onlineList[$friendId]) ? 1 : 0;
                if ($value['order_id']) {
                    $value['realname'] = OrderModel::where('id', $value['order_id'])->value('order_name');
                }
            }
            return $this->success($list);
        } catch (\Exception $exception) {
            return $this->error($exception->getMessage());
        }
    }
}